Concurrent Programming হচ্ছে একাধিক কাজ একযোগে সম্পন্ন করার প্রক্রিয়া, যেখানে একাধিক কার্যক্রম (threads বা processes) একে অপরের সাথে সমান্তরালভাবে (concurrently) কাজ করতে পারে। এটি ব্যবহৃত হয় যখন প্রোগ্রামটি একাধিক কাজ এক সাথে, সিমালটেনিয়াসলি সম্পন্ন করার ক্ষমতা রাখে। কনকারেন্ট প্রোগ্রামিংয়ের মূল লক্ষ্য হল ব্যবহৃত রিসোর্স (যেমন CPU) দক্ষভাবে ব্যবহার করা এবং কার্যক্রম দ্রুত শেষ করা।
রুবি ভাষায়, কনকারেন্ট প্রোগ্রামিং কিছু জনপ্রিয় কৌশল ব্যবহার করে, যেমন Threads, Fibers, Process Management, এবং Async I/O। এখানে আমরা এই কৌশলগুলি নিয়ে আলোচনা করব এবং কীভাবে এগুলি রুবিতে কার্যকরভাবে ব্যবহৃত হয় তা দেখাব।
১. Threads in Ruby
Threads হল রুবিতে কনকারেন্ট প্রোগ্রামিংয়ের একটি সাধারণ উপায়। একটি থ্রেড হলো একটি ছোট একক কার্যক্রম, যা একসাথে অন্যান্য থ্রেডের সাথে কার্যকরী হতে পারে। রুবিতে থ্রেড ব্যবহারে একাধিক কার্যক্রম একসাথে সম্পাদন করা সম্ভব।
Syntax:
thread = Thread.new do
# code to execute in the thread
end
thread.join # Wait for the thread to finishউদাহরণ:
# Create two threads to run two tasks concurrently
thread1 = Thread.new do
5.times do |i|
puts "Thread 1: #{i}"
sleep 1
end
end
thread2 = Thread.new do
5.times do |i|
puts "Thread 2: #{i}"
sleep 1
end
end
# Wait for both threads to complete
thread1.join
thread2.joinআউটপুট:
Thread 1: 0
Thread 2: 0
Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
Thread 1: 3
Thread 2: 3
Thread 1: 4
Thread 2: 4এখানে দুটি থ্রেডে আলাদা আলাদা কার্যক্রম চলেছে এবং একই সময়ে কাজ হয়েছে, যার ফলে কার্যক্রম দ্রুত সমাপ্ত হয়েছে।
Thread Safety:
থ্রেড ব্যবহারের সময় Thread Safety নিশ্চিত করা গুরুত্বপূর্ণ, কারণ একাধিক থ্রেড একসাথে একটি কমন রিসোর্স ব্যবহার করতে পারে এবং এতে ডেটা কনফ্লিক্ট হতে পারে। রুবিতে Mutex এবং Monitor ব্যবহার করে থ্রেড সেফটি নিশ্চিত করা যায়।
২. Fibers in Ruby
Fibers হল রুবির আরও এক কনকারেন্ট প্রোগ্রামিং টুল, যা lightweight থ্রেড হিসেবে কাজ করে। ফাইবার থ্রেডের তুলনায় আরও বেশি কার্যকরী এবং দ্রুত কাজ করে, কারণ এগুলি non-preemptive। একটি ফাইবার কার্যকরী না হলে অন্য ফাইবার চালাতে পারে, তবে তার পূর্ববর্তী ফাইবারটি explicitly স্টপ করতে হয়।
Syntax:
fiber = Fiber.new do
# code to run in the fiber
end
fiber.resume # Start the fiberউদাহরণ:
fiber1 = Fiber.new do
5.times do |i|
puts "Fiber 1: #{i}"
Fiber.yield # Yield control to the next fiber
end
end
fiber2 = Fiber.new do
5.times do |i|
puts "Fiber 2: #{i}"
Fiber.yield
end
end
# Resuming fibers
fiber1.resume
fiber2.resume
fiber1.resume
fiber2.resume
fiber1.resume
fiber2.resume
fiber1.resume
fiber2.resume
fiber1.resume
fiber2.resumeআউটপুট:
Fiber 1: 0
Fiber 2: 0
Fiber 1: 1
Fiber 2: 1
Fiber 1: 2
Fiber 2: 2
Fiber 1: 3
Fiber 2: 3
Fiber 1: 4
Fiber 2: 4এখানে, Fiber.yield মেথডটি এক ফাইবারের execution বন্ধ করে অন্য ফাইবারে control পাঠাচ্ছে। এটি আরও বেশি lightweight কনকারেন্ট প্রোগ্রামিংয়ের জন্য উপকারী।
৩. Process Management (Multiprocessing)
Multiprocessing হল এমন একটি পদ্ধতি যেখানে একাধিক প্রসেস একসাথে কাজ করে। রুবিতে Process ক্লাস ব্যবহার করে একাধিক প্রসেস চালানো সম্ভব।
Syntax:
process = Process.fork do
# code to execute in the new process
end
Process.wait # Wait for the process to finishউদাহরণ:
# Creating two separate processes
process1 = Process.fork do
5.times do |i|
puts "Process 1: #{i}"
sleep 1
end
end
process2 = Process.fork do
5.times do |i|
puts "Process 2: #{i}"
sleep 1
end
end
# Wait for both processes to finish
Process.wait(process1)
Process.wait(process2)এখানে, দুটি আলাদা প্রসেস একসাথে কাজ করছে। Process.fork নতুন প্রসেস তৈরি করে এবং Process.wait এটি শেষ হওয়া পর্যন্ত মূল প্রসেসে অপেক্ষা করে।
৪. Async I/O (Asynchronous Input/Output)
Asynchronous I/O (async I/O) হল এমন একটি প্রক্রিয়া যেখানে ইনপুট বা আউটপুট অপারেশনগুলি একে অপরের থেকে স্বাধীনভাবে কাজ করে, অর্থাৎ একটি অপারেশন সম্পন্ন হওয়ার জন্য অন্যটির অপেক্ষা করতে হয় না। এটি I/O-bound operations যেমন ফাইল রিডিং, নেটওয়ার্ক কল ইত্যাদির ক্ষেত্রে খুবই কার্যকরী।
রুবিতে EventMachine বা Async gem ব্যবহৃত হয় async I/O পরিচালনার জন্য।
উদাহরণ (Async I/O using EventMachine):
require 'eventmachine'
EM.run do
EM.add_timer(2) do
puts "This will be printed after 2 seconds"
EM.stop
end
endএখানে, EventMachine ব্যবহৃত হয়েছে asynchronous টাইমার পরিচালনা করার জন্য, যা নির্দিষ্ট সময় পরে একটি কাজ করবে এবং এদিকে অন্য কাজগুলো চলতে থাকবে।
৫. Actor Model for Concurrency
Actor Model হল একটি প্যাটার্ন যা রুবিতে কনকারেন্ট প্রোগ্রামিংয়ের জন্য কার্যকরী হতে পারে। এটি বিভিন্ন একক actors (অবজেক্ট) ব্যবহার করে, প্রতিটি actor একে অপরের থেকে স্বাধীনভাবে কাজ করতে পারে এবং তাদের মধ্যে মেসেজ পাস করার মাধ্যমে সমন্বয় করা হয়।
রুবি এদের ব্যবহারের জন্য Celluloid বা Concurrent-Ruby মতো লাইব্রেরি ব্যবহার করতে পারে।
উদাহরণ (using Concurrent-Ruby):
require 'concurrent-ruby'
actor = Concurrent::Actor.spawn(:actor1) do |message|
puts "Received message: #{message}"
end
actor.tell("Hello, Actor!")এখানে, actor একটি পৃথক থ্রেড বা প্রক্রিয়া হিসেবে কাজ করছে এবং অন্য মেসেজগুলি পাস করে তার কার্যক্রম সম্পন্ন করছে।
সারসংক্ষেপ
- Threads: রুবিতে Thread ক্লাস ব্যবহার করে একাধিক থ্রেডের মাধ্যমে কনকারেন্ট প্রোগ্রামিং করা যায়, যেখানে প্রতিটি থ্রেড একটি আলাদা কার্যক্রম পরিচালনা করে।
- Fibers: Fibers হল থ্রেডের তুলনায় আরো লাইটওয়েট কনকারেন্ট প্রোগ্রামিং টুল, যা কোডের নির্দিষ্ট অংশের উপর নিয়ন্ত্রণ রেখে অন্য অংশে কাজ করতে সাহায্য করে।
- Multiprocessing: একাধিক process ব্যবহারের মাধ্যমে একাধিক কাজ একসাথে করা হয়। এটি সিপিইউ-bounded অপারেশনগুলির জন্য উপকারী।
- Async I/O: Asynchronous I/O প্যাটার্ন ব্যবহার করে ইনপুট ও আউটপুট অপারেশনগুলি একে অপরের থেকে স্বাধীনভাবে কার্যকরী হতে পারে।
- Actor Model: Actor মডেল কনকারেন্ট প্রোগ্রামিংয়ে মেসেজ পাসিং এর মাধ্যমে একাধিক কার্যক্রম পরিচালনা করতে সহায়তা করে।
এই কনকারেন্ট প্রোগ্রামিং কৌশলগুলি রুবি প্রোগ্রামে কোডের কার্যকারিতা এবং দক্ষতা বৃদ্ধি করতে সাহায্য করে, বিশেষ করে যখন একাধিক কাজ সমান্তরালে সম্পন্ন করতে হয়।
Read more